package band.wukong.practice.netty.nettyinactionessential.ch02;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Desc:
 * author: wukonggg@139.com
 */
@ChannelHandler.Sharable    // 1.@Sharable标记这个类的实例可以在 channel 里共享
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    /*
        SimpleChannelInboundHandler vs. ChannelInboundHandler
        何时用这两个要看具体业务的需要。
        在客户端，当 channelRead0() 完成，我们已经拿到的入站的信息。
        当方法返回时，SimpleChannelInboundHandler 会小心的释放对 ByteBuf（保存信息） 的引用。
        而在 EchoServerHandler,我们需要将入站的信息返回给发送者，
        由于 write() 是异步的，在 channelRead() 返回时，可能还没有完成。
        所以，我们使用 ChannelInboundHandlerAdapter,无需释放信息。
        最后在 channelReadComplete() 我们调用 ctxWriteAndFlush() 来释放信息。详见第5、6章
    */

    private static final Logger log;
    static {
        log = LogManager.getLogger(EchoServer.class);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 2.当被通知该 channel 是活动的时候就发送信息
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        // 3.记录接收到的消息
        log.info("Client received: " + in.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 4.记录日志错误并关闭 channel
        cause.printStackTrace();
        ctx.close();
    }
}
